/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controladores;

import controladores.exceptions.IllegalOrphanException;
import controladores.exceptions.NonexistentEntityException;
import controladores.exceptions.PreexistingEntityException;
import entidades.Direccion;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.Transporteaereo;
import entidades.Transporteterrestre;
import entidades.Unidadorganizacional;
import entidades.Provedor;
import entidades.Ciudad;
import entidades.Restaurante;
import entidades.Hotel;
import entidades.Lugar;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Andres
 */
public class DireccionJpaController {

    public DireccionJpaController() {
        emf = Persistence.createEntityManagerFactory("proyectoCongresoPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Direccion direccion) throws PreexistingEntityException, Exception {
        if (direccion.getLugarList() == null) {
            direccion.setLugarList(new ArrayList<Lugar>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Transporteaereo transporteaereo = direccion.getTransporteaereo();
            if (transporteaereo != null) {
                transporteaereo = em.getReference(transporteaereo.getClass(), transporteaereo.getIdTransporte());
                direccion.setTransporteaereo(transporteaereo);
            }
            Transporteterrestre transporteterrestre = direccion.getTransporteterrestre();
            if (transporteterrestre != null) {
                transporteterrestre = em.getReference(transporteterrestre.getClass(), transporteterrestre.getIdTransporte());
                direccion.setTransporteterrestre(transporteterrestre);
            }
            Unidadorganizacional unidadorganizacional = direccion.getUnidadorganizacional();
            if (unidadorganizacional != null) {
                unidadorganizacional = em.getReference(unidadorganizacional.getClass(), unidadorganizacional.getCodigounidad());
                direccion.setUnidadorganizacional(unidadorganizacional);
            }
            Provedor provedor = direccion.getProvedor();
            if (provedor != null) {
                provedor = em.getReference(provedor.getClass(), provedor.getRut());
                direccion.setProvedor(provedor);
            }
            Ciudad ciudad = direccion.getCiudad();
            if (ciudad != null) {
                ciudad = em.getReference(ciudad.getClass(), ciudad.getCodigo());
                direccion.setCiudad(ciudad);
            }
            Restaurante restaurante = direccion.getRestaurante();
            if (restaurante != null) {
                restaurante = em.getReference(restaurante.getClass(), restaurante.getRecursosIdrecurso());
                direccion.setRestaurante(restaurante);
            }
            Hotel hotel = direccion.getHotel();
            if (hotel != null) {
                hotel = em.getReference(hotel.getClass(), hotel.getRecursosIdrecurso());
                direccion.setHotel(hotel);
            }
            List<Lugar> attachedLugarList = new ArrayList<Lugar>();
            for (Lugar lugarListLugarToAttach : direccion.getLugarList()) {
                lugarListLugarToAttach = em.getReference(lugarListLugarToAttach.getClass(), lugarListLugarToAttach.getRecursosIdrecurso());
                attachedLugarList.add(lugarListLugarToAttach);
            }
            direccion.setLugarList(attachedLugarList);
            em.persist(direccion);
            if (transporteaereo != null) {
                Direccion oldDireccionOfTransporteaereo = transporteaereo.getDireccion();
                if (oldDireccionOfTransporteaereo != null) {
                    oldDireccionOfTransporteaereo.setTransporteaereo(null);
                    oldDireccionOfTransporteaereo = em.merge(oldDireccionOfTransporteaereo);
                }
                transporteaereo.setDireccion(direccion);
                transporteaereo = em.merge(transporteaereo);
            }
            if (transporteterrestre != null) {
                Direccion oldDireccionOfTransporteterrestre = transporteterrestre.getDireccion();
                if (oldDireccionOfTransporteterrestre != null) {
                    oldDireccionOfTransporteterrestre.setTransporteterrestre(null);
                    oldDireccionOfTransporteterrestre = em.merge(oldDireccionOfTransporteterrestre);
                }
                transporteterrestre.setDireccion(direccion);
                transporteterrestre = em.merge(transporteterrestre);
            }
            if (unidadorganizacional != null) {
                Direccion oldDireccionOfUnidadorganizacional = unidadorganizacional.getDireccion();
                if (oldDireccionOfUnidadorganizacional != null) {
                    oldDireccionOfUnidadorganizacional.setUnidadorganizacional(null);
                    oldDireccionOfUnidadorganizacional = em.merge(oldDireccionOfUnidadorganizacional);
                }
                unidadorganizacional.setDireccion(direccion);
                unidadorganizacional = em.merge(unidadorganizacional);
            }
            if (provedor != null) {
                Direccion oldDireccionOfProvedor = provedor.getDireccion();
                if (oldDireccionOfProvedor != null) {
                    oldDireccionOfProvedor.setProvedor(null);
                    oldDireccionOfProvedor = em.merge(oldDireccionOfProvedor);
                }
                provedor.setDireccion(direccion);
                provedor = em.merge(provedor);
            }
            if (ciudad != null) {
                ciudad.getDireccionList().add(direccion);
                ciudad = em.merge(ciudad);
            }
            if (restaurante != null) {
                Direccion oldDireccionOfRestaurante = restaurante.getDireccion();
                if (oldDireccionOfRestaurante != null) {
                    oldDireccionOfRestaurante.setRestaurante(null);
                    oldDireccionOfRestaurante = em.merge(oldDireccionOfRestaurante);
                }
                restaurante.setDireccion(direccion);
                restaurante = em.merge(restaurante);
            }
            if (hotel != null) {
                Direccion oldDireccionOfHotel = hotel.getDireccion();
                if (oldDireccionOfHotel != null) {
                    oldDireccionOfHotel.setHotel(null);
                    oldDireccionOfHotel = em.merge(oldDireccionOfHotel);
                }
                hotel.setDireccion(direccion);
                hotel = em.merge(hotel);
            }
            for (Lugar lugarListLugar : direccion.getLugarList()) {
                Direccion oldDireccionOfLugarListLugar = lugarListLugar.getDireccion();
                lugarListLugar.setDireccion(direccion);
                lugarListLugar = em.merge(lugarListLugar);
                if (oldDireccionOfLugarListLugar != null) {
                    oldDireccionOfLugarListLugar.getLugarList().remove(lugarListLugar);
                    oldDireccionOfLugarListLugar = em.merge(oldDireccionOfLugarListLugar);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findDireccion(direccion.getCodigo()) != null) {
                throw new PreexistingEntityException("Direccion " + direccion + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Direccion direccion) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Direccion persistentDireccion = em.find(Direccion.class, direccion.getCodigo());
            Transporteaereo transporteaereoOld = persistentDireccion.getTransporteaereo();
            Transporteaereo transporteaereoNew = direccion.getTransporteaereo();
            Transporteterrestre transporteterrestreOld = persistentDireccion.getTransporteterrestre();
            Transporteterrestre transporteterrestreNew = direccion.getTransporteterrestre();
            Unidadorganizacional unidadorganizacionalOld = persistentDireccion.getUnidadorganizacional();
            Unidadorganizacional unidadorganizacionalNew = direccion.getUnidadorganizacional();
            Provedor provedorOld = persistentDireccion.getProvedor();
            Provedor provedorNew = direccion.getProvedor();
            Ciudad ciudadOld = persistentDireccion.getCiudad();
            Ciudad ciudadNew = direccion.getCiudad();
            Restaurante restauranteOld = persistentDireccion.getRestaurante();
            Restaurante restauranteNew = direccion.getRestaurante();
            Hotel hotelOld = persistentDireccion.getHotel();
            Hotel hotelNew = direccion.getHotel();
            List<Lugar> lugarListOld = persistentDireccion.getLugarList();
            List<Lugar> lugarListNew = direccion.getLugarList();
            List<String> illegalOrphanMessages = null;
            if (transporteaereoOld != null && !transporteaereoOld.equals(transporteaereoNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Transporteaereo " + transporteaereoOld + " since its direccion field is not nullable.");
            }
            if (transporteterrestreOld != null && !transporteterrestreOld.equals(transporteterrestreNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Transporteterrestre " + transporteterrestreOld + " since its direccion field is not nullable.");
            }
            if (provedorOld != null && !provedorOld.equals(provedorNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Provedor " + provedorOld + " since its direccion field is not nullable.");
            }
            if (restauranteOld != null && !restauranteOld.equals(restauranteNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Restaurante " + restauranteOld + " since its direccion field is not nullable.");
            }
            if (hotelOld != null && !hotelOld.equals(hotelNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Hotel " + hotelOld + " since its direccion field is not nullable.");
            }
            for (Lugar lugarListOldLugar : lugarListOld) {
                if (!lugarListNew.contains(lugarListOldLugar)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Lugar " + lugarListOldLugar + " since its direccion field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (transporteaereoNew != null) {
                transporteaereoNew = em.getReference(transporteaereoNew.getClass(), transporteaereoNew.getIdTransporte());
                direccion.setTransporteaereo(transporteaereoNew);
            }
            if (transporteterrestreNew != null) {
                transporteterrestreNew = em.getReference(transporteterrestreNew.getClass(), transporteterrestreNew.getIdTransporte());
                direccion.setTransporteterrestre(transporteterrestreNew);
            }
            if (unidadorganizacionalNew != null) {
                unidadorganizacionalNew = em.getReference(unidadorganizacionalNew.getClass(), unidadorganizacionalNew.getCodigounidad());
                direccion.setUnidadorganizacional(unidadorganizacionalNew);
            }
            if (provedorNew != null) {
                provedorNew = em.getReference(provedorNew.getClass(), provedorNew.getRut());
                direccion.setProvedor(provedorNew);
            }
            if (ciudadNew != null) {
                ciudadNew = em.getReference(ciudadNew.getClass(), ciudadNew.getCodigo());
                direccion.setCiudad(ciudadNew);
            }
            if (restauranteNew != null) {
                restauranteNew = em.getReference(restauranteNew.getClass(), restauranteNew.getRecursosIdrecurso());
                direccion.setRestaurante(restauranteNew);
            }
            if (hotelNew != null) {
                hotelNew = em.getReference(hotelNew.getClass(), hotelNew.getRecursosIdrecurso());
                direccion.setHotel(hotelNew);
            }
            List<Lugar> attachedLugarListNew = new ArrayList<Lugar>();
            for (Lugar lugarListNewLugarToAttach : lugarListNew) {
                lugarListNewLugarToAttach = em.getReference(lugarListNewLugarToAttach.getClass(), lugarListNewLugarToAttach.getRecursosIdrecurso());
                attachedLugarListNew.add(lugarListNewLugarToAttach);
            }
            lugarListNew = attachedLugarListNew;
            direccion.setLugarList(lugarListNew);
            direccion = em.merge(direccion);
            if (transporteaereoNew != null && !transporteaereoNew.equals(transporteaereoOld)) {
                Direccion oldDireccionOfTransporteaereo = transporteaereoNew.getDireccion();
                if (oldDireccionOfTransporteaereo != null) {
                    oldDireccionOfTransporteaereo.setTransporteaereo(null);
                    oldDireccionOfTransporteaereo = em.merge(oldDireccionOfTransporteaereo);
                }
                transporteaereoNew.setDireccion(direccion);
                transporteaereoNew = em.merge(transporteaereoNew);
            }
            if (transporteterrestreNew != null && !transporteterrestreNew.equals(transporteterrestreOld)) {
                Direccion oldDireccionOfTransporteterrestre = transporteterrestreNew.getDireccion();
                if (oldDireccionOfTransporteterrestre != null) {
                    oldDireccionOfTransporteterrestre.setTransporteterrestre(null);
                    oldDireccionOfTransporteterrestre = em.merge(oldDireccionOfTransporteterrestre);
                }
                transporteterrestreNew.setDireccion(direccion);
                transporteterrestreNew = em.merge(transporteterrestreNew);
            }
            if (unidadorganizacionalOld != null && !unidadorganizacionalOld.equals(unidadorganizacionalNew)) {
                unidadorganizacionalOld.setDireccion(null);
                unidadorganizacionalOld = em.merge(unidadorganizacionalOld);
            }
            if (unidadorganizacionalNew != null && !unidadorganizacionalNew.equals(unidadorganizacionalOld)) {
                Direccion oldDireccionOfUnidadorganizacional = unidadorganizacionalNew.getDireccion();
                if (oldDireccionOfUnidadorganizacional != null) {
                    oldDireccionOfUnidadorganizacional.setUnidadorganizacional(null);
                    oldDireccionOfUnidadorganizacional = em.merge(oldDireccionOfUnidadorganizacional);
                }
                unidadorganizacionalNew.setDireccion(direccion);
                unidadorganizacionalNew = em.merge(unidadorganizacionalNew);
            }
            if (provedorNew != null && !provedorNew.equals(provedorOld)) {
                Direccion oldDireccionOfProvedor = provedorNew.getDireccion();
                if (oldDireccionOfProvedor != null) {
                    oldDireccionOfProvedor.setProvedor(null);
                    oldDireccionOfProvedor = em.merge(oldDireccionOfProvedor);
                }
                provedorNew.setDireccion(direccion);
                provedorNew = em.merge(provedorNew);
            }
            if (ciudadOld != null && !ciudadOld.equals(ciudadNew)) {
                ciudadOld.getDireccionList().remove(direccion);
                ciudadOld = em.merge(ciudadOld);
            }
            if (ciudadNew != null && !ciudadNew.equals(ciudadOld)) {
                ciudadNew.getDireccionList().add(direccion);
                ciudadNew = em.merge(ciudadNew);
            }
            if (restauranteNew != null && !restauranteNew.equals(restauranteOld)) {
                Direccion oldDireccionOfRestaurante = restauranteNew.getDireccion();
                if (oldDireccionOfRestaurante != null) {
                    oldDireccionOfRestaurante.setRestaurante(null);
                    oldDireccionOfRestaurante = em.merge(oldDireccionOfRestaurante);
                }
                restauranteNew.setDireccion(direccion);
                restauranteNew = em.merge(restauranteNew);
            }
            if (hotelNew != null && !hotelNew.equals(hotelOld)) {
                Direccion oldDireccionOfHotel = hotelNew.getDireccion();
                if (oldDireccionOfHotel != null) {
                    oldDireccionOfHotel.setHotel(null);
                    oldDireccionOfHotel = em.merge(oldDireccionOfHotel);
                }
                hotelNew.setDireccion(direccion);
                hotelNew = em.merge(hotelNew);
            }
            for (Lugar lugarListNewLugar : lugarListNew) {
                if (!lugarListOld.contains(lugarListNewLugar)) {
                    Direccion oldDireccionOfLugarListNewLugar = lugarListNewLugar.getDireccion();
                    lugarListNewLugar.setDireccion(direccion);
                    lugarListNewLugar = em.merge(lugarListNewLugar);
                    if (oldDireccionOfLugarListNewLugar != null && !oldDireccionOfLugarListNewLugar.equals(direccion)) {
                        oldDireccionOfLugarListNewLugar.getLugarList().remove(lugarListNewLugar);
                        oldDireccionOfLugarListNewLugar = em.merge(oldDireccionOfLugarListNewLugar);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = direccion.getCodigo();
                if (findDireccion(id) == null) {
                    throw new NonexistentEntityException("The direccion with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Direccion direccion;
            try {
                direccion = em.getReference(Direccion.class, id);
                direccion.getCodigo();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The direccion with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Transporteaereo transporteaereoOrphanCheck = direccion.getTransporteaereo();
            if (transporteaereoOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Direccion (" + direccion + ") cannot be destroyed since the Transporteaereo " + transporteaereoOrphanCheck + " in its transporteaereo field has a non-nullable direccion field.");
            }
            Transporteterrestre transporteterrestreOrphanCheck = direccion.getTransporteterrestre();
            if (transporteterrestreOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Direccion (" + direccion + ") cannot be destroyed since the Transporteterrestre " + transporteterrestreOrphanCheck + " in its transporteterrestre field has a non-nullable direccion field.");
            }
            Provedor provedorOrphanCheck = direccion.getProvedor();
            if (provedorOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Direccion (" + direccion + ") cannot be destroyed since the Provedor " + provedorOrphanCheck + " in its provedor field has a non-nullable direccion field.");
            }
            Restaurante restauranteOrphanCheck = direccion.getRestaurante();
            if (restauranteOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Direccion (" + direccion + ") cannot be destroyed since the Restaurante " + restauranteOrphanCheck + " in its restaurante field has a non-nullable direccion field.");
            }
            Hotel hotelOrphanCheck = direccion.getHotel();
            if (hotelOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Direccion (" + direccion + ") cannot be destroyed since the Hotel " + hotelOrphanCheck + " in its hotel field has a non-nullable direccion field.");
            }
            List<Lugar> lugarListOrphanCheck = direccion.getLugarList();
            for (Lugar lugarListOrphanCheckLugar : lugarListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Direccion (" + direccion + ") cannot be destroyed since the Lugar " + lugarListOrphanCheckLugar + " in its lugarList field has a non-nullable direccion field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Unidadorganizacional unidadorganizacional = direccion.getUnidadorganizacional();
            if (unidadorganizacional != null) {
                unidadorganizacional.setDireccion(null);
                unidadorganizacional = em.merge(unidadorganizacional);
            }
            Ciudad ciudad = direccion.getCiudad();
            if (ciudad != null) {
                ciudad.getDireccionList().remove(direccion);
                ciudad = em.merge(ciudad);
            }
            em.remove(direccion);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Direccion> findDireccionEntities() {
        return findDireccionEntities(true, -1, -1);
    }

    public List<Direccion> findDireccionEntities(int maxResults, int firstResult) {
        return findDireccionEntities(false, maxResults, firstResult);
    }

    private List<Direccion> findDireccionEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Direccion.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Direccion findDireccion(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Direccion.class, id);
        } finally {
            em.close();
        }
    }

    public int getDireccionCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Direccion> rt = cq.from(Direccion.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
